package com.jic.product.controller.store;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.jic.common.base.vo.RestResult;
import com.jic.product.constant.consist.ResponseCode;
import com.jic.product.entity.Product;
import com.jic.product.entity.StoreInventory;
import com.jic.product.exception.AppRuntimeException;
import com.jic.product.model.entity.MStoreBalance;
import com.jic.product.model.entity.MStoreOperateLog;
import com.jic.product.model.entity.MStoreOperateProductlog;
import com.jic.product.model.vo.request.MStoreOperateProductInfoRequest;
import com.jic.product.model.vo.response.MStoreOperateProductInfoResponse;
import com.jic.product.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: 建投数据科技(山东)有限公司
 * @date: 2020-04-29 20:51:52
 */
@RestController
@Slf4j
@RequestMapping("/mStoreOperateProductInfo")
@Api(tags = " [实体库存操作记录明细]控制类-PC")
public class MStoreOperateProductInfoController {
    @Autowired
    private MStoreOperateProductInfoService service;

    @Autowired
    private MStoreBalanceService mStoreBalanceService;

    @Autowired
    private MStoreOperateService mStoreOperateService;

    @Autowired
    private StoreInventoryService storeInventoryService;
    @Autowired
    private ProductService productService;


    /**
     * 新增记录
     *
     * @param request 新增[实体库存操作记录明细]请求参数
     * @return MStoreOperateProductInfoResponse 新增[实体库存操作记录明细]响应参数
     * author 建投数据科技(山东)有限公司
     * @date 2020-3-11 20:54:04
     */
    @ApiOperation(value = "批量新增[实体库存操作记录明细]记录")
    @PostMapping("/saves")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public RestResult<Long> save(@RequestBody MStoreOperateProductInfoRequest request) throws Throwable {
        long flag = 0;
        //1.根据仓库id和商品id查询是否存在台账
        MStoreBalance queryBalance = new MStoreBalance();
        queryBalance.setProductId(request.getProductId());
        queryBalance.setStoreId(request.getStoreId());
        List<MStoreBalance> result = mStoreBalanceService.listAllRecord(queryBalance);
        if (result != null && result.size() > 0) {
            //2.如果存在台账 则在原有基础上修改
            MStoreBalance balance = result.get(0);
            //判断是加库还是减库
            if (null != request.getOperateFlag() && request.getOperateFlag() > 9) {//减库
                //判断减少的数量和台账可用数量大小
                long value = request.getApplyNum() - balance.getAvailable();
                if (value < 0) {//库存余额充足 可以直接减
                    balance.setAvailable(balance.getAvailable() - request.getApplyNum());
                    balance.setTotal(balance.getTotal() - request.getApplyNum());
                    balance.setDeptId(request.getAdminOperate().getDeptId());
                    mStoreBalanceService.saveOrUpdate(balance);
                    //保存operate_product_info记录
                    MStoreOperateProductlog mStoreOperateProductlog = new MStoreOperateProductlog();
                    BeanUtils.copyProperties(request, mStoreOperateProductlog);
                    mStoreOperateProductlog.setOperateId(request.getParentId());
                    mStoreOperateProductlog.setActualNum(request.getApplyNum());
                    mStoreOperateProductlog.setDeptId(request.getAdminOperate().getDeptId());
                    service.save(mStoreOperateProductlog);
                } else {
                    //
                    //保存operate_product_info记录
                    MStoreOperateProductlog mStoreOperateProductlog = new MStoreOperateProductlog();
                    BeanUtils.copyProperties(request, mStoreOperateProductlog);
                    mStoreOperateProductlog.setOperateId(request.getParentId());
                    //修改实际减少数量
                    mStoreOperateProductlog.setActualNum(balance.getAvailable());
                    mStoreOperateProductlog.setOperateId(request.getParentId());//父级别id
                    mStoreOperateProductlog.setBalanceId(balance.getId());
                    mStoreOperateProductlog.setApplyNum(request.getApplyNum());
                    mStoreOperateProductlog.setDeptId(request.getAdminOperate().getDeptId());
                    service.save(mStoreOperateProductlog);

                    //如果申请减少的数量大于可用余额 则把库存减少至0
                    balance.setAvailable(0L);
                    balance.setTotal(0L);
                    balance.setDeptId(request.getAdminOperate().getDeptId());
                    mStoreBalanceService.saveOrUpdate(balance);

                }

            } else {//加库

                if (request != null && request.getOperateId() != null && request.getOperateId() == 8) {
                    Long diffNum = request.getDiffNum();
                    if (diffNum < 0 && balance.getAvailable() + diffNum < 0) {
                        return RestResult.error("9999", "盘亏差异数量大于库存剩余,无法盘点");
                    }

                    balance.setAvailable(balance.getAvailable() + (request.getDiffNum() == null ? 0 : request.getDiffNum()));
                    balance.setTotal(balance.getTotal() + (request.getDiffNum() == null ? 0 : request.getDiffNum()));
                    balance.setDeptId(request.getAdminOperate().getDeptId());
                    mStoreBalanceService.saveOrUpdate(balance);

                    MStoreOperateLog mStoreOperate = new MStoreOperateLog();
                    mStoreOperate.setType(1);
                    mStoreOperate.setOrderId(null);
                    mStoreOperate.setDeleteFlag(0);
                    mStoreOperate.setStatus(0);
                    mStoreOperate.setOperateId(8L);
                    mStoreOperate.setOperateDesc("盘点出入库");
                    mStoreOperate.setApplyNum(diffNum);
                    mStoreOperate.setActualNum(diffNum);
                    mStoreOperate.setBalanceId(balance.getId());
                    mStoreOperate.setProductId(request.getProductId());
                    mStoreOperate.setBatchNo(null);
                    if (diffNum >= 0) {
                        mStoreOperate.setCalculateType("+");
                    } else {
                        mStoreOperate.setCalculateType("-");
                    }
                    mStoreOperate.setCheckStatus(null);
                    mStoreOperate.setCode(request.getCode());
                    mStoreOperate.setLocation(request.getLocation());
                    mStoreOperate.setDeptName(request.getDeptName());
                    mStoreOperate.setProductCode(request.getProductCode());
                    mStoreOperate.setProductName(request.getProductName());
                    mStoreOperate.setRemark(request.getRemark());
                    mStoreOperate.setStoreId(request.getStoreId());
                    mStoreOperate.setDeptId(request.getAdminOperate().getDeptId());
//                    mStoreOperateService.saveOrUpdate(mStoreOperate);

                    List<MStoreOperateLog> mStoreOperates = mStoreOperateService.listAllRecord(mStoreOperate);
                    if (mStoreOperates != null && mStoreOperates.size() == 1) {
                        //保存operate_product_info记录
                        MStoreOperateProductlog mStoreOperateProductlog = new MStoreOperateProductlog();
                        BeanUtils.copyProperties(request, mStoreOperateProductlog);
                        mStoreOperateProductlog.setOperateId(mStoreOperates.get(0).getId());
                        mStoreOperateProductlog.setBalanceId(balance.getId());
                        mStoreOperateProductlog.setActualNum(diffNum);
                        mStoreOperateProductlog.setApplyNum(diffNum);
                        mStoreOperateProductlog.setDeptId(request.getAdminOperate().getDeptId());
                        flag = service.save(mStoreOperateProductlog);
                    } else {
                        throw new AppRuntimeException("获取到多条M_STORE_OPERATE记录");
                    }
                } else {
                    balance.setAvailable(balance.getAvailable() + (request.getApplyNum() == null ? 0 : request.getApplyNum()));
                    balance.setTotal(balance.getTotal() + request.getApplyNum());
                    balance.setDeptId(request.getAdminOperate().getDeptId());
                    mStoreBalanceService.saveOrUpdate(balance);

                    MStoreOperateLog mStoreOperate = new MStoreOperateLog();
                    mStoreOperate.setType(1);
                    mStoreOperate.setOrderId(null);
                    mStoreOperate.setDeleteFlag(0);
                    mStoreOperate.setStatus(0);
                    mStoreOperate.setOperateId(8L);
                    mStoreOperate.setOperateDesc("盘点出入库");
                    mStoreOperate.setApplyNum(request.getApplyNum());
                    mStoreOperate.setActualNum(request.getActualNum());
                    mStoreOperate.setBalanceId(balance.getId());
                    mStoreOperate.setProductId(request.getProductId());
                    mStoreOperate.setBatchNo(null);
                    if (request.getApplyNum() >= 0) {
                        mStoreOperate.setCalculateType("+");
                    } else {
                        mStoreOperate.setCalculateType("-");
                    }
                    mStoreOperate.setCheckStatus(null);
                    mStoreOperate.setCode(request.getCode());
                    mStoreOperate.setLocation(request.getLocation());
                    mStoreOperate.setDeptName(request.getDeptName());
                    mStoreOperate.setProductCode(request.getProductCode());
                    mStoreOperate.setProductName(request.getProductName());
                    mStoreOperate.setRemark(request.getRemark());
                    mStoreOperate.setStoreId(request.getStoreId());
                    mStoreOperate.setDeptId(request.getAdminOperate().getDeptId());
//                    mStoreOperateService.saveOrUpdate(mStoreOperate);

                    //保存operate_product_info记录
                    MStoreOperateProductlog mStoreOperateProductlog = new MStoreOperateProductlog();
                    BeanUtils.copyProperties(request, mStoreOperateProductlog);
                    mStoreOperateProductlog.setOperateId(request.getParentId());
                    mStoreOperateProductlog.setBalanceId(balance.getId());
                    mStoreOperateProductlog.setActualNum(request.getApplyNum());
                    mStoreOperateProductlog.setDeptId(request.getAdminOperate().getDeptId());
                    flag = service.save(mStoreOperateProductlog);
                }
            }
        } else {
            //新增此商品台账记录
            MStoreBalance balance = new MStoreBalance();
            balance.setStoreId(request.getStoreId());
            balance.setTotal(0L);
            balance.setAvailable(0L);
            balance.setBlock(0L);
            balance.setProductId(request.getProductId());
            balance.setDeleteFlag(0);
            balance.setCreateTime(new Date());
            balance.setUpdateTime(new Date());
            balance.setDeptId(request.getAdminOperate().getDeptId());
            mStoreBalanceService.saveOrUpdate(balance);
            MStoreBalance queryParams = new MStoreBalance();
            queryParams.setStoreId(request.getStoreId());
            queryParams.setProductId(request.getProductId());
            queryParams.setDeleteFlag(0);
            List<MStoreBalance> list = mStoreBalanceService.listAllRecord(queryParams);
            MStoreBalance mStoreBalance = null;
            if (list != null && list.size() > 0) {
                mStoreBalance = list.get(0);
            }
            //判断是加库还是减库操作
            if (request.getOperateFlag() > 9) {//减库
                //保存operate_product_info记录
                MStoreOperateProductlog mStoreOperateProductlog = new MStoreOperateProductlog();
                BeanUtils.copyProperties(request, mStoreOperateProductlog);
                mStoreOperateProductlog.setOperateId(request.getParentId());
                mStoreOperateProductlog.setActualNum(0L);
                mStoreOperateProductlog.setBalanceId(mStoreBalance.getId());
                mStoreOperateProductlog.setDeptId(request.getAdminOperate().getDeptId());
                service.save(mStoreOperateProductlog);
                //新增operate_product记录
            } else {//加库
                mStoreBalance.setAvailable(request.getApplyNum());
                mStoreBalance.setTotal(request.getApplyNum());
                mStoreBalance.setDeptId(request.getAdminOperate().getDeptId());
                mStoreBalanceService.saveOrUpdate(mStoreBalance);
                //新增operate_product记录
            }
        }

//            }
//        }
        return RestResult.success(flag);
    }


    /**
     * 新增库内事物单详细信息
     * @param request
     * @return
     * @throws Throwable
     */
    @ApiOperation(value = "新增库内事物当详细信息")
    @PostMapping("/saveProductInfo")
    @ResponseBody
//    @Transactional(rollbackFor = Exception.class)
    public RestResult<Long> saveProductInfo(@RequestBody MStoreOperateProductInfoRequest request) throws Throwable {
        long flag = 0;
        //拿到operateId
        Long parentId = request.getParentId();
        if (parentId != null && parentId > 0) {
            MStoreOperateProductlog mStoreOperateProductlog = new MStoreOperateProductlog();
            BeanUtils.copyProperties(request, mStoreOperateProductlog);
            mStoreOperateProductlog.setOperateId(parentId);
            mStoreOperateProductlog.setDeptId(request.getAdminOperate().getDeptId());
            flag = service.saveOrUpdate(mStoreOperateProductlog);
            //判断商品是否存在台账
            MStoreBalance queryBalance = new MStoreBalance();
            queryBalance.setProductId(request.getProductId());
            queryBalance.setStoreId(request.getStoreId());

            List<MStoreBalance> result = mStoreBalanceService.listAllRecord(queryBalance);
            if (result == null || result.size() == 0) {
                //新增此商品台账记录
                MStoreBalance balance = new MStoreBalance();
                balance.setStoreId(request.getStoreId());
                balance.setTotal(0L);
                balance.setAvailable(0L);
                balance.setBlock(0L);
                balance.setProductId(request.getProductId());
                balance.setDeleteFlag(0);
                balance.setCreateTime(new Date());
                balance.setUpdateTime(new Date());
                balance.setDeptId(request.getAdminOperate().getDeptId());
                mStoreBalanceService.saveOrUpdate(balance);
            }
        } else {
            return RestResult.error("9999", "库内事物单主体信息不能为空！");
        }


        return RestResult.success(flag);
    }

    /**
     * 新增或修改记录
     *
     * @param request 新增或修改[实体库存操作记录明细]请求参数
     * @return MStoreOperateProductInfoResponse 新增或修改[实体库存操作记录明细]响应参数
     * author 建投数据科技(山东)有限公司
     * @date 2020-3-11 20:54:04
     */
    @ApiOperation(value = "保存或更新[实体库存操作记录明细]")
    @PostMapping("/saveOrUpdate")
    @ResponseBody
    public RestResult<Long> saveOrUpdate(@Validated @RequestBody MStoreOperateProductInfoRequest request) throws Throwable {
        MStoreOperateProductlog mStoreOperateProductlog = new MStoreOperateProductlog();
        BeanUtils.copyProperties(request, mStoreOperateProductlog);
        long flag = service.saveOrUpdate(mStoreOperateProductlog);
        return RestResult.success(flag);
    }

    /**
     * 删除记录
     *
     * @param request 删除[实体库存操作记录明细]请求参数
     * @return MStoreOperateProductInfoResponse 删除[实体库存操作记录明细]响应参数
     * author 建投数据科技(山东)有限公司
     * @date 2020-3-11 20:54:04
     */
    @ApiOperation(value = "删除[实体库存操作记录明细]记录")
    @PostMapping("/delete")
    @ResponseBody
    public RestResult<Long> delete(@RequestBody MStoreOperateProductInfoRequest request) throws Throwable {
        MStoreOperateProductlog mStoreOperateProductlog = new MStoreOperateProductlog();
        BeanUtils.copyProperties(request, mStoreOperateProductlog);
        long flag = service.deleteByPrimaryKeyLogically(mStoreOperateProductlog);
        return RestResult.success(flag);
    }

    /**
     * 修改记录
     *
     * @param request 修改[实体库存操作记录明细]请求参数
     * @return MStoreOperateProductInfoResponse 修改[实体库存操作记录明细]响应参数
     * author 建投数据科技(山东)有限公司
     * @date 2020-3-11 20:54:04
     */
    @ApiOperation(value = "修改[实体库存操作记录明细]记录")
    @PostMapping("/update")
    @ResponseBody
    public RestResult<Long> update(@RequestBody MStoreOperateProductInfoRequest request) throws Throwable {
        MStoreOperateProductlog mStoreOperateProductlog = new MStoreOperateProductlog();
        BeanUtils.copyProperties(request, mStoreOperateProductlog);
        long flag = service.updateByPrimaryKeySelective(mStoreOperateProductlog);
        return RestResult.success(flag);
    }

    /**
     * 单表查询详情信息
     *
     * @param request 查询[实体库存操作记录明细]详情请求参数
     * @return MStoreOperateProductInfoResponse 查询[实体库存操作记录明细]详情响应参数
     * author 建投数据科技(山东)有限公司
     * @date 2020-3-11 20:54:04
     */
    @PostMapping("/getByPrimaryKey")
    @ApiOperation(value = "查询[实体库存操作记录明细]详情")
    @ResponseBody
    public RestResult<MStoreOperateProductInfoResponse> getByPrimaryKey(@Validated @RequestBody MStoreOperateProductInfoRequest request) {
        log.info("查询详情请求参数入参，{}", JSONObject.toJSONString(request));
        if (request != null && request.getId() != null) {

            MStoreOperateProductlog mStoreOperateProductlog = new MStoreOperateProductlog();
            BeanUtils.copyProperties(request, mStoreOperateProductlog);
            MStoreOperateProductlog result = service.getByPrimaryKey(mStoreOperateProductlog);
            log.info("查询详情请求参数出参，{}", JSONObject.toJSONString(result));
            if (result == null) {
                return RestResult.error(ResponseCode.EXCEPTION, "记录不存在");
            }
            MStoreOperateProductInfoResponse bo = new MStoreOperateProductInfoResponse();
            BeanUtils.copyProperties(result, bo);
            return RestResult.success(bo);
        }
        log.info("查询详情请求结束");
        return RestResult.success(null);
    }

    /**
     * 分页查询
     *
     * @param request 分页查询请求参数
     * @return 分页列表
     * @throws Throwable 业务异常和系统异常
     */
    @PostMapping("/listPage")
    @ApiOperation(value = " 分页查询列表 ")
    @ResponseBody
    public RestResult<PageInfo<MStoreOperateProductlog>> listPage(@RequestBody MStoreOperateProductInfoRequest request) throws Throwable {
        MStoreOperateProductlog param = new MStoreOperateProductlog();
        BeanUtils.copyProperties(request, param);
        return RestResult.success(service.listPageBySelective(param, request.getPageNum(), request.getPageSize()));
    }

    /**
     * M_STORE_OPERATE_PRODUCT_INFO 查询列表（不分页）
     *
     * @param request 前端请求参数
     */
    @PostMapping("/listAll")
    @ApiOperation(value = "不分页查询 [实体库存操作记录明细] ")
    @ResponseBody
    public RestResult<List<MStoreOperateProductInfoResponse>> listMStoreOperateProductInfoAllRecord(@RequestBody MStoreOperateProductInfoRequest request) throws Throwable {
        MStoreOperateProductlog mStoreOperateProductlog = new MStoreOperateProductlog();
        BeanUtils.copyProperties(request, mStoreOperateProductlog);

        List<MStoreOperateProductlog> list = service.listAllRecord(mStoreOperateProductlog);
        List<MStoreOperateProductInfoResponse> responseList = list.stream().map(temp -> {
            MStoreOperateProductInfoResponse bo = new MStoreOperateProductInfoResponse();
            BeanUtils.copyProperties(temp, bo);
            bo.setChineseName(temp.getProductName());
            bo.setCode(temp.getProductCode());
            StoreInventory storeInventory=new StoreInventory();
            storeInventory.setProductId(temp.getProductId());
            storeInventory.setDeleteFlag(0);
            List<StoreInventory> inventoryList = storeInventoryService.query(storeInventory);
           if(CollectionUtils.isNotEmpty(inventoryList)){
               bo.setAvailableStock(inventoryList.get(0).getAvailableStock());
           }
            return bo;
        }).filter(item -> item != null).collect(Collectors.toList());
        return RestResult.success(responseList);
    }


    @PostMapping("/importRuleCheck")
    @ApiOperation(value = "校验导入明细规则")
    @ResponseBody
    public RestResult<MStoreOperateProductInfoResponse> importRuleCheck(@RequestBody MStoreOperateProductInfoRequest request) throws Throwable {
        //商品必须是商家下的仓库中的商品  根据code和名称检索商品
        //申请数量、实际处理数量：验证为正整数，否则不允许导入
        if (request != null) {
            if (request.getActualNum() > 0 && request.getApplyNum() > 0) {
            } else {
                return RestResult.error("9999", "申请数量和处理数量必须为正数");
            }
            //校验商品是否存在
            if (StringUtils.isNotEmpty(request.getChineseName()) && StringUtils.isNotEmpty(request.getProductCode())) {
                Product product = new Product();
                product.setCode(request.getProductCode());
                product.setChineseName(request.getChineseName());
                List<Product> products = productService.queryAll(product);
                if (products != null && products.size() > 0) {
                    Product result = products.get(0);
                    MStoreOperateProductInfoResponse response = new MStoreOperateProductInfoResponse();
                    response.setActualNum(request.getActualNum());
                    response.setApplyNum(request.getApplyNum());
                    response.setArtNo(result.getArtNo());
                    response.setChineseName(result.getChineseName());
                    response.setProductCode(result.getCode());
                    response.setBarCode(result.getBarCode());
                    response.setProductId(result.getId());
                    return RestResult.success(response);
                } else {
                    return RestResult.error("9999", "商品名：" + request.getChineseName() + "的商品不存在");
                }
            } else {
                return RestResult.error("9999", "商品编码和名称不能为空");
            }


        }

        return RestResult.success(null);
    }

    @PostMapping("/importRuleForCheck")
    @ApiOperation(value = "校验导入明细规则")
    @ResponseBody
    public RestResult<MStoreOperateProductInfoResponse> importRuleCheckForCheck(@RequestBody MStoreOperateProductInfoRequest request) throws Throwable {
        //商品必须是商家下的仓库中的商品  根据code和名称检索商品
        //申请数量、实际处理数量：验证为正整数，否则不允许导入
        if (request != null) {
            if (StringUtils.isNotBlank(request.getProductCode())) {
            } else {
                return RestResult.error("9999", "产品编号不能为空");
            }
            if (StringUtils.isNotBlank(request.getChineseName())) {
            } else {
                return RestResult.error("9999", "中文名称不能为空");
            }

            if (request.getCheckNum() > 0 && request.getCheckNum() > 0) {
            } else {
                return RestResult.error("9999", "申请数量和处理数量必须为正数");
            }
            //校验商品是否存在
            if (StringUtils.isNotEmpty(request.getChineseName()) && StringUtils.isNotEmpty(request.getProductCode())) {
                Product product = new Product();
                product.setCode(request.getProductCode());
                product.setChineseName(request.getChineseName());
                List<Product> products = productService.queryAll(product);
                if (products != null && products.size() > 0) {
                    Product result = products.get(0);
                    MStoreOperateProductInfoResponse response = new MStoreOperateProductInfoResponse();
                    response.setActualNum(request.getActualNum());
                    response.setApplyNum(request.getApplyNum());
                    response.setArtNo(result.getArtNo());
                    response.setChineseName(result.getChineseName());
                    response.setProductCode(result.getCode());
                    response.setBarCode(result.getBarCode());
                    response.setProductId(result.getId());
                    response.setCheckNum(request.getCheckNum());
                    response.setDiffNum(request.getDiffNum());
                    return RestResult.success(response);
                } else {
                    return RestResult.error("9999", "商品名：" + request.getChineseName() + "的商品不存在");
                }
            } else {
                return RestResult.error("9999", "商品编码和名称不能为空");
            }


        }

        return RestResult.success(null);
    }

}

